package com.neusoft.neuiotms.dcvm.controller;

import java.io.IOException;
import java.util.stream.Collectors;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.neusoft.bizcore.auth.common.bean.UserBean;
import com.neusoft.bizcore.auth.common.jwt.JwtAuthProvider;
import com.neusoft.bizcore.auth.service.AuthUserService;
import com.neusoft.bizcore.webauth.secret.AuditOplogService;
import com.ultrapower.casp.client.LoginUtil;
import com.ultrapower.casp.common.code.ResultCode;
import com.ultrapower.casp.common.datatran.data.ticket.TransferTicket;
import com.ultrapower.casp.common.datatran.data.user.UserInfo;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
public class CaspController {

    @Value("${casp.configFilePath:''}")
    private String caspConfigFilePath;
    //    @Value("${casp.adminAccountId:admin}")
    //    private String adminAccountId;
    @Value("${casp.nginxIndexUrl:''}")
    private String nginxIndexUrl;

    @Autowired
    private AuditOplogService auditOplogService;

    @Autowired
    private AuthUserService authUserService;

    @RequestMapping("/casp")
    public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        CaspController.log.info("casp login start");
        LoginUtil.getInstance().init(this.caspConfigFilePath);

        if (LoginUtil.getInstance().isEnable()) {
            if (LoginUtil.getInstance().checkTicket(request)) {
                final String strTic = LoginUtil.getInstance().getTicket(request);
                final TransferTicket ticket = LoginUtil.getInstance().analysTicket(strTic);
                if ((ticket != null) && (ticket.getRetCode() != null)
                        && ResultCode.RESULT_OK.equals(ticket.getRetCode())) {
                    // TODO: userInfo中的accountID有可能就是从账号ID
                    final UserInfo userInfo = LoginUtil.getInstance().qryUserByTicket(ticket);
                    if (null != userInfo) {
                        CaspController.log.info("从账号：{}", userInfo.getAccountID());
                    } else {
                        CaspController.log.error("通过LoginUtil.getInstance().qryUserByTicket(ticket)获取从账号返回null");
                    }

                    if ((null != userInfo) && !ResultCode.RESULT_OK.equals(userInfo.getRetCode())) {
                        // 跳转到错误页面，显示错误码；
                        CaspController.log.warn("获取用户信息错误，错误码：{}。重定向到原登录画面", userInfo.getRetCode());
                        response.sendRedirect(this.nginxIndexUrl);

                    } else {
                        // 应用资源根据帐号信息做登录后业务处理；
                        // userInfo中的accountID有可能就是从账号ID
                        final String localUser = userInfo.getAccountID();

                        final UserBean userBean = this.authUserService.loadUserByUsername(localUser);
                        // 管控平台主账户没有关联从账号
                        if (null == userBean) {
                            // 删除Cookie
                            final Cookie cookie = new Cookie("Authentication", "");
                            cookie.setPath("/");
                            cookie.setMaxAge(0);
                            response.addCookie(cookie);
                            response.sendRedirect(this.nginxIndexUrl);
                            return;
                        }
                        this.loginOk(request, response, localUser);
                    }
                } else {
                    // 跳转到错误页面，显示错误码；
                    CaspController.log.warn("获取票据出错，错误码：{}。重定向到原登录画面",
                            null != ticket ? ticket.getRetCode() : "analysTicket is null");
                    response.sendRedirect(this.nginxIndexUrl);
                    // 模拟认证成功
                    //this.loginOk(response, "admin");
                }
                return;
            }
            if (LoginUtil.getInstance().hasAliveServer()) {
                LoginUtil.getInstance().redirectToServer(request, response);
            } else {
                CaspController.log.warn("没有可用的服务器，重定向到原登录画面");
                response.sendRedirect(this.nginxIndexUrl);
            }
        } else {
            response.sendRedirect(this.nginxIndexUrl);
        }

    }

    private void loginOk(HttpServletRequest request, HttpServletResponse response, String localUser)
            throws IOException {
        final JwtAuthProvider jwtAuthProvider =
                new JwtAuthProvider(1000 * 24 * 60 * 60 * 1000, "secret");

        final UserBean userBean = this.authUserService.loadUserByUsername(localUser);
        final String token = jwtAuthProvider.generateToken(localUser,
                userBean.getRoles().stream().map(it -> it.getRole()).collect(Collectors.toList()));

        this.auditOplogService.create(localUser, request.getHeader("x-forwarded-for") == null
                ? request.getRemoteAddr() : request.getHeader("x-forwarded-for"), "3D可视化", "Login", "登录成功");

        final Cookie cookie = new Cookie("Authentication", token);
        cookie.setPath("/");
        cookie.setMaxAge(-1);
        response.addCookie(cookie);

        response.sendRedirect(this.nginxIndexUrl);
    }
}
